import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;//导入包

enum Direction { UP, DOWN, LEFT, RIGHT }//方向枚举

class SnakeGame extends JFrame {//主类定义
    private static final int SIZE = 20;
    private static final int WIDTH = 30;
    private static final int HEIGHT = 30;
    private List<Point> snake = new ArrayList<>();
    private Point food;
    private Direction direction = Direction.RIGHT;
    private int score = 0;
    private boolean gameOver = false;//成员变量

    public SnakeGame() {
        initUI();
        startGame();
    }//构造方法

    private void initUI() {//界面初始化
        setTitle("贪吃蛇");//设置窗口标题
        setSize(WIDTH * SIZE, HEIGHT * SIZE);//设置窗口大小
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭窗口时退出程序
        setLocationRelativeTo(null);//窗口居中显示
        addKeyListener(new KeyAdapter() {//添加键盘监听器
            @Override
            public void keyPressed(KeyEvent e) {
                switch (e.getKeyCode()) {
                    case KeyEvent.VK_UP://不能反向移动
                        if (direction != Direction.DOWN) direction = Direction.UP;
                        break;
                    case KeyEvent.VK_DOWN:
                        if (direction != Direction.UP) direction = Direction.DOWN;
                        break;
                    case KeyEvent.VK_LEFT:
                        if (direction != Direction.RIGHT) direction = Direction.LEFT;
                        break;
                    case KeyEvent.VK_RIGHT:
                        if (direction != Direction.LEFT) direction = Direction.RIGHT;
                        break;
                }
            }
        });
        setVisible(true);//显示窗口
    }

    private void startGame() {
        initializeSnake();//初始化蛇的初始状态
        generateFood();
        
        new Thread(() -> {//启动游戏逻辑线程（多线程核心）
            while (!gameOver) {//游戏未结束循环
                try {
                    Thread.sleep(150);//控制移动速度
                    moveSnake();//移动蛇
                    checkCollision();//检测碰撞
                    repaint();//重绘界面
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
            showGameOver();
        }).start();
    }

    private void initializeSnake() {//蛇的初始化
        snake.clear();
        snake.add(new Point(WIDTH/2, HEIGHT/2));
        snake.add(new Point(WIDTH/2-1, HEIGHT/2));
        snake.add(new Point(WIDTH/2-2, HEIGHT/2));
    }

    private void generateFood() {//生成食物
        Random random = new Random();
        do {
            food = new Point(random.nextInt(WIDTH), random.nextInt(HEIGHT));
        } while (snake.contains(food));
    }

    private void moveSnake() {//移动蛇
        Point head = snake.get(0);
        switch (direction) {
            case UP: head = new Point(head.x, head.y - 1); break;
            case DOWN: head = new Point(head.x, head.y + 1); break;
            case LEFT: head = new Point(head.x - 1, head.y); break;
            case RIGHT: head = new Point(head.x + 1, head.y); break;
        }
        snake.add(0, head);
        
        if (!head.equals(food)) {
            snake.remove(snake.size() - 1);
        } else {
            score += 10;
            generateFood();
        }
    }//移动蛇

    private void checkCollision() {//碰撞检测
        Point head = snake.get(0);  
        // 边界碰撞检测
        if (head.x < 0 || head.x >= WIDTH || head.y < 0 || head.y >= HEIGHT) {
            gameOver = true;
        }
        // 自身碰撞检测
        for (int i = 1; i < snake.size(); i++) {
            if (head.equals(snake.get(i))) {
                gameOver = true;
                break;
            }
        }
    }//碰撞检测 

    private void showGameOver() {
        JOptionPane.showMessageDialog(this, 
            "游戏结束！得分：" + score, 
            "Game Over", 
            JOptionPane.INFORMATION_MESSAGE);
        System.exit(0);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;
        
        // 绘制蛇
        for (Point p : snake) {
            g2d.fillRect(p.x * SIZE, p.y * SIZE, SIZE-1, SIZE-1);
        }
        
        // 绘制食物
        g2d.setColor(Color.RED);
        g2d.fillOval(food.x * SIZE, food.y * SIZE, SIZE-1, SIZE-1);
        
        // 绘制边界
        g2d.setColor(Color.BLACK);
        g2d.drawRect(0, 0, WIDTH*SIZE-1, HEIGHT*SIZE-1);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(SnakeGame::new);
    }
}